﻿/*              Copyright(c) 2008 Dave Sexton              *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DaveSexton.DocToMaml.Maml;

namespace DaveSexton.DocToMaml
{
	internal abstract class InputBase : IInput, IDisposable
	{
		#region Public Properties
		public string FullPath { get; private set; }

		public string Name
		{
			get
			{
				return System.IO.Path.GetFileName(FullPath);
			}
		}

		public string Log
		{
			get
			{
				using (System.IO.StringWriter writer = new System.IO.StringWriter(System.Globalization.CultureInfo.CurrentCulture))
				{
					WriteLog(writer);
					return writer.ToString();
				}
			}
		}

		public abstract IEnumerable<string> Files { get; }

		public abstract ICollection<Exception> ConversionErrors { get; }

		public abstract string ConceptualArtFileXml { get; }

		public ConceptualImageManager Images
		{
			get
			{
				return images;
			}
		}

		public FileGuidManager Guids
		{
			get
			{
				return guids;
			}
		}

		public IRuleContainer Rules
		{
			get
			{
				return rules;
			}
		}

		public abstract ICollection<IInput> Subinputs { get; }
		#endregion

		#region Private / Protected
		private readonly ConceptualImageManager images;
		private readonly FileGuidManager guids;
		private readonly RuleContainer rules = new RuleContainer();
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="InputBase" /> class for derived classes.
		/// </summary>
		protected InputBase(string path, ConceptualImageManager imageManager, FileGuidManager guidManager)
		{
			if (string.IsNullOrEmpty(path))
				throw new ArgumentException(Resources.Errors.NullOrEmpty, "path");

			if (imageManager == null)
				throw new ArgumentNullException("imageManager");

			if (guidManager == null)
				throw new ArgumentNullException("guidManager");

			FullPath = path;
			this.images = imageManager;
			this.guids = guidManager;
		}
		#endregion

		#region Methods
		public abstract int Convert(string targetFolder);

		public void WriteLog(System.IO.TextWriter writer)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");

			WriteLogStart(writer);
			WriteLogContents(writer);
			WriteLogEnd(writer);
		}

		protected virtual void WriteLogStart(System.IO.TextWriter writer)
		{
			writer.WriteLine("Source: {0}", FullPath);
		}

		protected virtual void WriteLogContents(System.IO.TextWriter writer)
		{
			writer.WriteLine();
		}

		protected virtual void WriteLogEnd(System.IO.TextWriter writer)
		{
			writer.WriteLine("---");
		}

		public override string ToString()
		{
			return FullPath;
		}
		#endregion

		#region IDisposable Members
		/// <summary>
		/// Releases all resources used by an instance of the <see cref="InputBase" /> class.
		/// </summary>
		/// <remarks>
		/// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in <strong>true</strong>, and then suppresses 
		/// finalization of the instance.
		/// </remarks>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// Releases unmanaged resources before an instance of the <see cref="InputBase" /> class is reclaimed by garbage collection.
		/// </summary>
		/// <remarks>
		/// This method releases unmanaged resources by calling the virtual <see cref="Dispose(bool)" /> method, passing in <strong>false</strong>.
		/// </remarks>
		~InputBase()
		{
			Dispose(false);
		}

		/// <summary>
		/// Releases the unmanaged resources used by an instance of the <see cref="InputBase" /> class and optionally releases the managed resources.
		/// </summary>
		/// <param name="disposing"><strong>true</strong> to release both managed and unmanaged resources; <strong>false</strong> to release only unmanaged resources.</param>
		protected virtual void Dispose(bool disposing)
		{
			// do nothing
		}
		#endregion
	}
}
